package com.heima.comment.service.impl;

import com.heima.comment.service.CommentRepayService;
import com.heima.common.exception.CustException;
import com.heima.feigns.UserFeign;
import com.heima.model.comment.dtos.CommentRepayDTO;
import com.heima.model.comment.dtos.CommentRepayLikeDTO;
import com.heima.model.comment.dtos.CommentRepaySaveDTO;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.comment.pojos.ApCommentRepayLike;
import com.heima.model.comment.vos.ApCommentRepayVO;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentRepayServiceImpl implements CommentRepayService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    UserFeign userFeign;

    /**
     * 加载评论回复列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult loadCommentRepay(CommentRepayDTO dto) {
        //TODO 检查参数
        if (dto.getSize()==null||dto.getSize()<=0){
            dto.setSize(10);
        }
        if (dto.getMinDate()==null){
            dto.setMinDate(new Date());
        }
        //TODO 根据评论id及创建时间小于最小时间查询评论恢复列表，按着创建时间降序排序
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId())
                .and("createdTime").lt(dto.getMinDate()))
                .limit(dto.getSize())
                .with(Sort.by(Sort.Direction.DESC, "createdTime"));
        //调用mongodb获取评论恢复列表集合
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);

        //todo 判断是否登录,如果未登录或回复的集合是空的  那么直接返回集合
        ApUser user = AppThreadLocalUtils.getUser();
        if(user==null||apCommentRepays==null){
            return ResponseResult.okResult(apCommentRepays);
        }
        //todo 3.2 如果登录了  并且 集合不为空 判断 当前回复列表中 哪些回复点过赞  --修改VO对象中operation字段为0
        List<String> commentRepayIds = apCommentRepays.stream()
                .map(ApCommentRepay::getId)
                .collect(Collectors.toList());
        //==---------------------
        // 用户id = user.getId    commentRepayId in 集合
        Query likedCommentRepay = Query.query(Criteria.where("authorId").is(user.getId())
                .and("commentRepayId").in(commentRepayIds));
        // 得到当前回复列表中 ，点过赞的集合
        List<ApCommentRepayLike> apCommentRepayLikes =
                mongoTemplate.find(likedCommentRepay, ApCommentRepayLike.class);

        if(apCommentRepayLikes !=null &&apCommentRepayLikes.size()>0){
            List<String> likedCommentRepayIds =
                    apCommentRepayLikes.stream()
                    .map(ApCommentRepayLike::getCommentRepayId)
                    .collect(Collectors.toList());

            // 说明有点过赞的回复
            List<ApCommentRepayVO> apCommentRepayVoList = new ArrayList<>();
            apCommentRepays.forEach(apCommentRepay -> {
                ApCommentRepayVO apCommentRepayVo = new ApCommentRepayVO();
                BeanUtils.copyProperties(apCommentRepay,apCommentRepayVo);
                if(likedCommentRepayIds.contains(apCommentRepay.getId())){
                    apCommentRepayVo.setOperation((short)0);
                }
                apCommentRepayVoList.add(apCommentRepayVo);
            });
            return ResponseResult.okResult(apCommentRepayVoList);
        }
        return ResponseResult.okResult(apCommentRepays);

    }

    /**
     *  保存评论回复
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveCommentRepay(CommentRepaySaveDTO dto) {
        //TODO 检查参数（评论id 评论容 是否登录）
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //TODO 阿里云文本检测
        //TODO 远程获取登录用户信息
        ResponseResult<ApUser> userResult = userFeign.findUserById(user.getId());
        if (userResult.getCode()!=0){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,userResult.getErrorMessage());
        }
        user = userResult.getData();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"当前登录信息有误");
        }
        //TODO 保存评论恢复信息--添加
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(user.getId());
        apCommentRepay.setAuthorName(user.getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.insert(apCommentRepay);

        //TODO 更新评论信息的恢复数量+1
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        apComment.setReply(apComment.getReply()+1);//在原评论数量的基础上+1
        mongoTemplate.save(apComment);

        return ResponseResult.okResult();
    }

    /**
     * 保存评论回复点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveCommentRepayLike(CommentRepayLikeDTO dto) {
        //TODO 检查参数 （评论回复id 方式是否正确 是否登录）
        ApUser user = AppThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //TODO 根据评论回复id查询评论回复信息
        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        if (apCommentRepay==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //todo 检查登录用户是否点过赞，提醒重复点赞
        Query query = Query.query(Criteria.where("authorId").is(user.getId())
                .and("commentRepayId").is(apCommentRepay.getId()));
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(query, ApCommentRepayLike.class);

        if (dto.getOperation().intValue()==0&&apCommentRepayLikes!=null){
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW,"请勿重复操作点赞");
        }
        //TODO 如果方式为0代表点赞
        if (dto.getOperation()==0){
            // todo 评论回复点赞+1
            apCommentRepay.setLikes(apCommentRepay.getLikes()+1);
            mongoTemplate.save(apCommentRepay);

            //  todo 添加评论回复点赞信息
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setAuthorId(user.getId());
            apCommentRepayLike.setCommentRepayId(apCommentRepay.getId());
            apCommentRepayLike.setOperation(dto.getOperation());
            mongoTemplate.save(apCommentRepayLike);
        }else {
            //TODO 如果方式为1代表取消点赞
            if (apCommentRepayLikes==null){
                CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST,"你还没有点赞");
            }
            //todo 评论回复点赞-1
            apCommentRepay.setLikes(apCommentRepay.getLikes()<0?0:apCommentRepay.getLikes()-1);
            mongoTemplate.save(apCommentRepay);
            //todo 删除评论点赞回复信息
            mongoTemplate.remove(query,ApCommentRepayLike.class);
        }

        //TODO 返回点赞数量
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("likes",apCommentRepay.getLikes());
        return ResponseResult.okResult(resultMap);
    }
}
